🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: rec.games.programmer
Article #1456

Re: Write Mode 1 on EGA/VGA cards

#1456
From: Paul Gallagher
Date: Tue, 23 Apr 1991 12:41
457 lines
12040 bytes
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
Technical Details
Message-ID: <1991Apr23.124108.28314@bhpmrl.oz.au>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!mips!spool.mu.edu!munnari.oz.au!bruce!merlin!paulg
References: <1991Apr15.061148.29923@watcgl.waterloo.edu> <28041@uflorida.cis.ufl.EDU> <1991Apr17.135925.9063@bhpmrl.oz.au> <1991Apr17.154316.9832@watcgl.waterloo.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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