Xref: utzoo rec.games.programmer:3494 comp.os.msdos.programmer:4850 Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!mips!spool.mu.edu!munnari.oz.au!bruce!merlin!paulg From: paulg@bhpmrl.oz.au (Paul Gallagher) Newsgroups: rec.games.programmer,comp.os.msdos.programmer Subject: Re: Write Mode 1 on EGA/VGA cards Message-ID: <1991Apr23.124108.28314@bhpmrl.oz.au> Date: 23 Apr 91 12:41:08 GMT References: <1991Apr15.061148.29923@watcgl.waterloo.edu> <28041@uflorida.cis.ufl.EDU> <1991Apr17.135925.9063@bhpmrl.oz.au> <1991Apr17.154316.9832@watcgl.waterloo.edu> Sender: usenet@bhpmrl.oz.au (USEnet nntp account) Organization: BHP Research - Melbourne Laboratories, AUSTRALIA Lines: 457 I've got to agree that the IBM PC graphics cards are certainly not the bee's knees, but they are a _challenge_! Why write code once, when you can do it over and over for the various screen modes?!? I'm attaching some ASM, based on an example in "Power graphics programming". NB: I just pulled this file off my hard disk - I think it's the right one. It should animate 6 multicolored balls bouncing around the screen (EGA/VGA) with no screen flicker, and at a respectable speed even on a 4.77MHz XT. (this is an intereseting point - the animation speed, since it is keyed to the vertical retrace, is totally dependant on the video hardware. The processors actually idling for much of the time. The implication is that there is still time left to do direction-velocity calculations, collision detection etc. You will note that in this example the ball vectors are pre-determined, and the only collisions are those with the side of the scren ) It illustrates the use of VRAM for storing sprites - a feature I think you were interested in? Regards, PaulG. PS: Sorry, the code is not documented well. /\/\ Paul Gallagher, PC Support Officer, / / /\ Computer Systems Group, / / / \ BHP Melbourne Research Laboratories / / / /\ \ 245 Wellington Rd Mulgrave Vic 3170 AUSTRALIA \ \/ / / / Phone : +61-3-560-7066, Fax : +61-3-561-6709 \ / / / ACSnet : paulg@bhpmrl.OZ.AU \/\/\/ Code begins here--------------------------------------------------------> ; written for TASM in MASM mode .MODEL SMALL .STACK 512 hires equ 0 VidSeg equ 0A000h ScrWidth equ 640/8 ScrHeight equ 350 Page0 equ 0 Page1 equ 1 Page0Offs equ 0 Page1Offs equ ScrWidth*ScrHeight Xlow equ 1 Xhi equ Scrwidth-4 Ylow equ 8 Yhi equ ScrHeight-Ylow-24 BallWidth equ 24/8 BallHeight equ 24 BlankOffs equ Page1Offs*2 Ball0Offs equ BlankOffs+(BallWidth*BallHeight) Ball1Offs equ Ball0Offs+(BallWidth*BallHeight) NumBalls equ 6 SCIndex equ 3C4h MapMask equ 2 GCIndex equ 3CEh GCMode equ 5 CRTCIndex equ 03D4h StartAddressHi equ 0Ch StartAddressLo equ 0Dh CRTCOffs equ 13h StatusRegister1 equ 03DAh VSyncMask equ 08h .DATA CurrentPage db Page1 CurrentPageOffs dw Page1Offs BallPlane0Image LABEL byte db 000h, 000h, 000h db 000h, 000h, 000h ; blue plane db 000h, 000h, 000h db 000h, 001h, 000h ; db 000h, 003h, 080h db 000h, 001h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; BallPlane1Image LABEL byte db 000h, 000h, 000h db 000h, 003h, 000h ; green plane db 000h, 007h, 0C0h db 000h, 00Fh, 0E0h ; db 000h, 00Fh, 0E0h db 000h, 00Fh, 0E0h ; db 000h, 007h, 0C0h db 000h, 003h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; BallPlane2Image LABEL byte db 000h, 03Ch, 000h db 001h, 0FFh, 080h ; red plane db 007h, 0FFh, 0E0h db 00Fh, 0FFh, 0F0h ; db 01Fh, 0FFh, 0F8h db 03Fh, 0FFh, 0FCh ; db 03Fh, 0FFh, 0FCh db 07Fh, 0FFh, 0FEh ; db 07Fh, 0FFh, 0FEh db 03Fh, 0FFh, 0FFh ; db 03Fh, 0FFh, 0FFh db 03Fh, 0FFh, 0FFh ; db 01Fh, 0FFh, 0FFh db 01Fh, 0FFh, 0FFh ; db 00Fh, 0FFh, 0FFh db 007h, 0FFh, 0FEh ; db 001h, 0FFh, 0FCh db 000h, 03Fh, 0F8h ; db 000h, 007h, 0F0h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; db 000h, 000h, 000h db 000h, 000h, 000h ; BallPlane3Image LABEL byte db 000h, 03Ch, 000h db 001h, 0FFh, 080h ; intensity plane db 007h, 0FFh, 0E0h db 00Fh, 0FFh, 0F0h ; db 007h, 0FFh, 0F8h db 007h, 0FFh, 0FCh ; db 003h, 0FFh, 0FCh db 001h, 0FFh, 0FEh ; db 000h, 0FFh, 0FEh db 0C0h, 07Fh, 0FFh ;* db 0C0h, 07Fh, 0FEh db 0C0h, 03Fh, 0FCh ; db 0E0h, 01Fh, 0F0h db 0E0h, 00Fh, 0C0h ; db 0F0h, 000h, 000h db 078h, 000h, 000h ; db 07Eh, 000h, 002h db 03Fh, 0C0h, 004h ; db 03Fh, 0F8h, 00Ch db 01Fh, 0FFh, 0F8h ; db 00Fh, 0FFh, 0F0h db 007h, 0FFh, 0E0h ; db 001h, 0FFh, 080h db 000h, 03Ch, 000h ; BallX dw 50, 12, 50, 35, 20, 2 BallY dw 230, 100, 300, 50, 150, 180 LastBallX dw 50, 12, 50, 35, 20, 1 LastBallY dw 230, 100, 300, 50, 150, 180 LLastBallX dw 50, 12, 50, 35, 20, 1 LLastBallY dw 230, 100, 300, 50, 150, 180 BallXInc dw 2, 1, -1, -1, 1, 2 BallYInc dw -4, 1, 2, 8, -3, -1 BallOffs dw Ball0Offs,Ball1Offs dw Ball1Offs,Ball0Offs dw Ball0Offs,Ball1Offs .CODE SETREG macro p1,p2 mov dx,p1 mov ah,al mov al,p2 out dx,ax ENDM DrawBall macro LOCAL writeballLoop mov ax,ScrWidth mul dx add ax,cx add ax,[CurrentPageOffs] mov di,ax mov bp,BallHeight push ds push es pop ds WriteBallLoop: push di mov cx,BallWidth rep movsb pop di add di,ScrWidth dec bp jnz WriteBallLoop pop ds endm start PROC near mov ax,@data mov ds,ax IFDEF hires mov ax,010h ELSE mov ax,0eh ENDIF int 10h mov ax,VidSeg mov es,ax mov di,Page0Offs call DrawBorder mov di,Page1Offs call DrawBorder mov al,01h SETREG SCIndex,MapMask mov si,OFFSET BallPlane0Image mov di,Ball0Offs mov cx,BallWidth * BallHeight rep movsb mov si,OFFSET BallPlane1Image mov di,Ball1Offs mov cx,BallWidth * BallHeight rep movsb mov al,02h SETREG SCIndex,MapMask mov si,OFFSET BallPlane1Image mov di,Ball0Offs mov cx,BallWidth * BallHeight rep movsb mov si,OFFSET BallPlane2Image mov di,Ball1Offs mov cx,BallWidth * BallHeight rep movsb mov al,04h SETREG SCIndex,MapMask mov si,OFFSET BallPlane2Image mov di,Ball0Offs mov cx,BallWidth * BallHeight rep movsb mov si,OFFSET BallPlane0Image mov di,Ball1Offs mov cx,BallWidth * BallHeight rep movsb mov al,08h SETREG SCIndex,MapMask mov si,OFFSET BallPlane3Image mov di,Ball0Offs mov cx,BallWidth * BallHeight rep movsb mov si,OFFSET BallPlane3Image mov di,Ball1Offs mov cx,BallWidth * BallHeight rep movsb mov al,0fh SETREG SCIndex,MapMask mov di,BlankOffs mov cx,BallWidth * BallHeight sub al,al rep stosb mov al,1 SETREG GCIndex,GCMode mov al,ScrWidth/2 SETREG CRTCIndex,CRTCOffs BallAnimLoop: mov bx,(NumBalls*2)-2 MoveBallLoop: mov ax,[LastBallX+bx] mov [lLastBallX+bx],ax mov ax,[BallX+bx] mov [LastBallX+bx],ax add ax,[BallXInc+bx] cmp ax,Xlow jle Border1test cmp ax,Xhi jle NextY Border1test: neg [BallXinc+bx] NextY: mov ax,[BallXInc+bx] add [BallX+bx],ax mov ax,[LastBallY+bx] mov [LLastBallY+bx],ax mov ax,[BallY+bx] mov [LastBallY+bx],ax add ax,[BallYInc+bx] cmp ax,Ylow jle Border2test cmp ax,Yhi jle NextYY Border2test: neg [BallYinc+bx] NextYY: mov ax,[BallYInc+bx] add [BallY+bx],ax dec bx dec bx jns MoveBallLoop mov bx,(NumBalls*2)-2 DrawBallLoop: mov si,BlankOffs mov cx,[LLastBallX+bx] mov dx,[LLastBallY+bx] DrawBall mov si,[BallOffs+bx] mov cx,[BallX+bx] mov dx,[BallY+bx] DrawBall dec bx dec bx jns DrawBallLoop ; call WaitVSync mov ax,[CurrentPageOffs] push ax SETREG CRTCIndex,StartAddressLo pop ax mov al,ah SETREG CRTCIndex,StartAddressHi call WaitVSync xor [CurrentPage],1 jnz IsPage1 mov [CurrentPageOffs],Page0Offs jmp short EndFlipPage IsPage1: mov [CurrentPageOffs],Page1Offs EndFlipPage: mov ah,1 int 16h jnz done jmp BallAnimLoop Done: mov ah,0 int 10h mov ax,3 int 10h mov ah,4ch int 21h start endp WaitVSync proc near mov dx,StatusRegister1 WaitNotVSyncLoop: in al,dx and al,VSyncMask jnz WaitNotVSyncLoop WaitVSyncLoop: in al,dx and al,VSyncMask jz WaitVSyncLoop ret WaitVSync endp DrawBorder proc near push di mov cx,ScrHeight/16 DrawLeftBorderLoop: mov al,0ch call DrawBorderBlock add di,ScrWidth*8 mov al,0eh call DrawBorderBlock add di,ScrWidth*8 loop DrawLeftBorderLoop pop di push di add di,ScrWidth-1 mov cx,ScrHeight/16 DrawRightBorderLoop: mov al,0eh call DrawBorderBlock add di,ScrWidth*8 mov al,0ch call DrawBorderBlock add di,ScrWidth*8 loop DrawRightBorderLoop pop di push di mov cx,(ScrWidth-2)/2 DrawTopBorderLoop: inc di mov al,0eh call DrawBorderBlock inc di mov al,0ch call DrawBorderBlock loop DrawTopBorderLoop pop di add di,(ScrHeight-8)*ScrWidth mov cx,(ScrWidth-2)/2 DrawBottomBorderLoop: inc di mov al,0ch call DrawBorderBlock inc di mov al,0eh call DrawBorderBlock loop DrawBottomBorderLoop ret DrawBorder endp DrawBorderBlock proc near push di SETREG SCIndex,MapMask mov al,0ffh rept 8 stosb add di,ScrWidth-1 endm pop di ret DrawBorderBlock endp end start