home *** CD-ROM | disk | FTP | other *** search
- ; ATIVGA module for IMDISP
- ;
- ; ATIVGA contains the device dependent display routines for
- ; ATI VGA Wonder graphics card with 512K memory. These routines
- ; were written specifically to support the 640x480x256, 800x600x256,
- ; and 1024x768x16 modes.
- ; This module was adapted, coded and tested by:
- ;
- ; Ron Baalke
- ; Jet Propulsion Lab
- ; M/S 301-355
- ; 4800 Oak Grove Dr.
- ; Pasadena, CA 91109
- ;
- ; These routines were written to support the IMDISP program. There are
- ; four routines which are called directly by IMDISP:
- ;
- ; ATI_Init - Initializes the graphics board.
- ; ATI_WritePalette - Writes the color palette out to the board.
- ; ATI_ReadPixel - Reads a pixel value given x,y coordinates
- ; ATI_WritePixel - Writes a pixel value to gvin x,y coordinate.
- ; ATI_Bank - Sets the card to one of its 8 banks
- ;
- ; Two external variables are used by this routines to indicate which
- ; video is being used. They must be initialized before any of the
- ; routines in this file are called. They are:
- ;
- ; dispns - Number of samples (columns)
- ; dispnl - Number of lines (rows)
- ;
- ; dispns = 640 selects the 640x480x256 mode
- ; dispns = 800 selects the 800x500x256 mode
- ; dispsn = 1024 select the 1024x768x16 mode
- ;
- ; Also, another external variable, atibank, is used in conjunction
- ; with the ATI_Bank routine to force the card to be a particular
- ; bank (optional, but handy to use for clearing the screen)
- ;
-
-
- .model large,c
- .data
- OSEG equ DS: ;segment override for variable access
-
- bankadr dw ?
- if @Codesize
- bankseg dw ?
- endif
-
- atibank dw ?
- ativga dw ?
- retval dw ? ;first return value from ATI_Init()
- dispns dw ?
- dispnl dw ?
- public dispns,dispnl ;these variables tells the routines which
- ;graphics mode to use
- public atibank
-
- .code
-
- public ATI_Init
- public ATI_WritePalette
- public ATI_WritePixel
- public ATI_ReadPixel
- public ATI_Bank
-
- ; ATI_Bank is used internally to select between one of 8 video banks on
- ; the ATI card.
-
- ATI_Bank proc ;bank number is in AX
- cli
- mov OSEG[atibank],ax
- if @Codesize
- jmp dword ptr OSEG[bankadr]
- else
- jmp word ptr OSEG[bankadr]
- endif
-
-
-
- _ativga:: ;ATI VGA Wonder
- push ax
- push dx
- mov ah,al
- mov dx,1ceh
- mov al,0b2h
- out dx,al
- inc dl
- in al,dx
- shl ah,1
- and al,0e1h
- or ah,al
- mov al,0b2h
- dec dl
- out dx,ax
- sti
- pop dx
- pop ax
- ret
-
- ATI_Bank endp
-
- ; ATI_Mode select the correct video mode
-
- ATI_Mode proc
- mov ah,0h
- cmp [dispns],1024
- jz m1024 ;1024x768x16
- cmp [dispns],800
- jz m800 ;800x600x256
- mov ax,62h ;640x480x256
- jmp godo
- m800: mov ax,63h
- jmp godo
- m1024: mov ax,65h
- godo: int 10h
-
- mov [atibank],-1
-
- nots: ret
- ATI_Mode endp
-
- ; ATI_WritePalette writes out the color palette (256 array) out to
- ; the board.
-
- ATI_WritePalette proc palbuf:ptr byte,begcol:word,numcol:word
- if @Datasize
- les dx,[palbuf]
- else
- mov ax,ds
- mov es,ax
- mov dx,[palbuf]
- endif
- mov bx,[begcol]
- mov cx,[numcol]
- mov ax,1012h
- int 10h
- ret
- ATI_WritePalette endp
-
- ; ATI_1024addr is used internally and computes the correct address
- ; (1024x768x16 mode only).
-
- ATI_1024addr proc
- clc ; clear carry flag
- push ax ; save this for a tad
- mov ax,dispns ; this many dots / line
- mul dx ; times this many lines - ans in dx:ax
- add ax,cx ; plus this many x-dots
- adc dx,0 ; answer in dx:ax
- shr dx,1 ; shift the answer right one bit
- rcr ax,1 ; .. in the 32-bit DX:AX combo
- mov bx,ax ; save this in BX
- cmp dx,atibank ; see if bank changed
- je atisame_bank ; jump if old bank ok
- mov ax,dx ; ATI_Bank expects bank in al
- call ATI_Bank
- atisame_bank:
- pop ax ; restore AX
- ret
- ATI_1024addr endp
-
- ; ATI_WritePixel writes out the color pixel at the x,y coordinate
-
- ATI_WritePixel proc xpos:word,ypos:word,color:word
- cmp [dispns],1024
- jz w1024
- jmp wskip
- w1024: mov ax,0a000h
- mov es,ax
- mov cx,[xpos]
- mov dx,[ypos]
- mov ax,[color]
- call ATI_1024addr ; calculate the address
- mov dl,es:[bx] ; get the byte the pixel is in
- and al,00fh ; zero out the high-order color bits
- test cl,1 ; is X odd?
- jz atiwritehigh ; Nope. Use the high bits
- and dl,0f0h ; zero out the low-order video bits
- or dl,al ; add the two together
- mov es:[bx],dl ; and write the results
- ret
- atiwritehigh:
- mov cl,4 ; shift the color bits
- shl al,cl ; ...
- and dl,0fh ; zero out the high-order video bits
- or dl,al ; add the two together
- mov es:[bx],dl ; and write the results
- ret
- wskip: mov bx,[xpos]
- mov ax,[ypos]
- mov dx,[dispns]
- cmp bx,0
- jl nope1
- cmp bx,dx
- jge nope1
- cmp ax,0
- jl nope1
- cmp ax,[dispnl]
- jge nope1
- mul dx ;800 dots wide
- add bx,ax
- adc dx,0
- mov ax,dx
- cmp ax,[atibank]
- jz nonew
- call ATI_Bank ;switch banks if a new bank entered
- nonew: mov ax,0a000h ;setup screen segment A000
- mov es,ax
- mov al,byte ptr [color] ;get color of pixel to plot
- mov es:[bx],al
- nope1: ret
- ATI_WritePixel endp
-
- ; ATI_ReadPixel reads the pixel value at the given x,y coordinate
-
- ATI_ReadPixel proc xpos:word,ypos:word
- cmp [dispns],1024
- jz r1024
- jmp rskip
- r1024: mov ax,0a000h
- mov es,ax
- mov cx,[xpos]
- mov dx,[ypos]
- call ATI_1024addr ; calculate the address
- mov al,es:[bx] ; get the byte the pixel is in
- test cl,1 ; is X odd?
- jz atireadhigh ; Nope. Use the high bits
- and ax,0fh ; zero out the high-order bits
- mov [retval],ax
- ret
- atireadhigh:
- and ax,0f0h ; zero out the low-order bits
- mov cl,4 ; shift the results
- shr al,cl ; ...
- mov [retval],ax
- ret
- rskip: mov bx,[xpos]
- mov ax,[ypos]
- mov dx,[dispns]
- cmp bx,0
- jl nope
- cmp bx,dx
- jge nope
- cmp ax,0
- jl nope
- cmp ax,[dispnl]
- jge nope
- mul dx ;800 dots wide
- add bx,ax
- adc dx,0
- mov ax,dx
- cmp ax,[atibank]
- jz nobank
- call ATI_Bank ;switch banks if a new bank entered
- nobank: mov ax,0a000h ;setup screen segment A000
- mov es,ax
- mov ax, byte ptr es:[bx] ;get color pixel
- mov [retval],ax
- nope: ret
- ATI_ReadPixel endp
-
-
- bkadr macro func
- mov [func],1
- mov [bankadr],offset _&func
- if @Codesize
- mov [bankseg],seg _&func
- endif
- endm
-
- nojmp macro
- local lbl
- jmp lbl
- lbl:
- endm
-
-
- ATI_Init proc uses si
- mov [atibank],0
- mov [ativga],0
- bkadr ativga
- cli
- mov dx,1ceh
- mov al,0bbh
- out dx,al
- inc dl
- in al,dx
- sti
- and al,20h
- call ATI_Mode
- fini: mov ax,si
- mov [retval],ax
- ret
- ATI_Init endp
-
- end
-
-